home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Palettes / TTools / TToolsPalette / TBinderList.subproj / TBinderListConnectInspector.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  10.4 KB  |  389 lines

  1. /* TBinderListConnectInspector.m
  2.  * Written By:  Thomas Burkholder
  3.  *
  4.  * You may freely copy, distribute, and reuse the code in this example.
  5.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  6.  * fitness for any particular use.
  7.  */
  8.  
  9.  
  10. #import "TBinderListConnectInspector.h"
  11. #import "TConnector.h"
  12. #import "TDataSourceConnector.h"
  13. #import "TBinderList.h"
  14. #import "TBinder.h"
  15. #import "TBinderInspector.h"
  16. #import "SelPairAgent.h"
  17. #import "SelectorBrowsingFunctions.h"
  18. #import "../Utilities.subproj/SortedList.h"
  19. #import "../Utilities.subproj/ConnectorAgent.h"
  20. #import "../Utilities.subproj/ClassAdditions.h"
  21. #import "../Utilities.subproj/SortedStorage.h"
  22.  
  23. static BOOL selecting;
  24.  
  25. @implementation TBinderListConnectInspector
  26.  
  27. id getDSConnectorForSource(id anObject)
  28. {
  29.     id sList = [[List alloc] init];
  30.     id dsConnector;
  31.  
  32.     [[NXApp activeDocument] listConnectors:sList forSource:anObject
  33.                         filterClass:[TDataSourceConnector class]];
  34.     dsConnector = [sList objectAt:0];
  35.     [sList free];
  36.     return dsConnector;
  37. }
  38.  
  39. id getTConnectorForDestination(id anObject)
  40. {
  41.     id sList = [[List alloc] init];
  42.     id tConnector;
  43.  
  44.     [[NXApp activeDocument] listConnectors:sList forDestination:anObject
  45.                         filterClass:[TConnector class]];
  46.     tConnector = [sList objectAt:0];
  47.     [sList free];
  48.     return tConnector;
  49. }
  50.  
  51. - init
  52. {
  53.     char buf[MAXPATHLEN + 1];
  54.     id bundle;
  55.     
  56.     [super init];
  57.     
  58.     bundle = [NXBundle bundleForClass:[TBinderList class]];
  59.     [bundle getPath:buf forResource:"TBinderListConnectInspector" ofType:"nib"];
  60.     [NXApp loadNibFile:buf owner:self withNames:NO fromZone:[self zone]];
  61.     [browser setDoubleAction:@selector(inspectBinderAfterDelay:)];
  62.     [connectorList setAgent:[[ConnectorAgent alloc] init]];
  63.     [accessorBrowser getTitleFromPreviousColumn:NO];
  64.     [accessorBrowser setTitle:"DataSource" ofColumn:0];
  65.     [accessorStorage setAgent:
  66.                     [[SelPairAgent alloc] initFrom:accessorStorage]];
  67.     [browser setEmptySelectionEnabled:YES];
  68.     [browser loadColumnZero];
  69.     
  70.     selecting = NO;
  71.     
  72.     return self;
  73. }
  74.  
  75. - inspectorView
  76. {
  77.     return inspectorView;
  78. }
  79.  
  80. - inspectBinderAfterDelay:sender
  81. {
  82.     [self perform:@selector(inspectBinder:) with:sender afterDelay:0
  83.                         cancelPrevious:NO];
  84.     return self;
  85. }
  86.  
  87. - inspectBinder:sender
  88. {
  89.     id isv = [inspectorView superview];
  90.     id binderView = [binderInspector inspectorView];
  91.     id conn=[connectorList objectAt:[[browser matrixInColumn:0]selectedRow]];
  92.  
  93.     [[isv window] disableFlushWindow];
  94.     [isv replaceSubview:inspectorView with:binderView];
  95.     [binderInspector inspectBinder:[conn binder] andReturnTo:self];
  96.     [[binderView window] display];
  97.     [[binderView window] reenableFlushWindow];
  98.     [[binderView window] flushWindow];
  99.     return self;
  100. }
  101.  
  102. - selectAccessor:sender
  103. {
  104.     id conn;
  105.     int col;
  106.  
  107.     // if there's no connection to apply it to, return.
  108.     if (![[browser matrixInColumn:0] selectedCell])
  109.         return self;
  110.  
  111.     // okay, we need to change the connection's binder:
  112.     col = [accessorBrowser selectedColumn];
  113.     conn = [connectorList objectAt:[[browser matrixInColumn:0] selectedRow]];
  114.     if (0==col) {
  115.         SEL s = sel_getUid([[[accessorBrowser matrixInColumn:0]
  116.                                 selectedCell] stringValue]);
  117.         if (s!=[[conn binder] dataSourceAccessor]) {
  118.             [[conn binder] setDataSourceAccessor:s];
  119.             [[conn binder] setDataSourceModifier:modifierFor(s)];
  120.  
  121.             // lets try not to lose the interfaceAccessor:
  122.             [self showConnection:conn];
  123.             if (![accessorBrowser selectedColumn]) { 
  124.                 [[conn binder] setInterfaceAccessor:(SEL)0];
  125.                 [[conn binder] setInterfaceModifier:(SEL)0];
  126.             }
  127.         }
  128.     } else if (1==col) {
  129.         SEL s = sel_getUid([[[accessorBrowser matrixInColumn:1]
  130.                                 selectedCell] stringValue]);
  131.         [[conn binder] setInterfaceAccessor:s];
  132.         [[conn binder] setInterfaceModifier:modifierFor(s)];
  133.     } else {
  134.         [[conn binder] setDataSourceAccessor:(SEL)0];
  135.         [[conn binder] setDataSourceModifier:(SEL)0];
  136.  
  137.         [[conn binder] setInterfaceAccessor:(SEL)0];
  138.         [[conn binder] setInterfaceModifier:(SEL)0];
  139.     }
  140.     return self;
  141. }
  142.  
  143. - selectDSConnection:sender
  144. {
  145.     id dsConnector = getDSConnectorForSource(object);
  146.     selecting = YES;
  147.     if ([sourceDisplayButton state]) {
  148.         [NXApp displayConnectionBetween:[dsConnector source] and:
  149.                         [dsConnector destination]];
  150.     } else {
  151.         [NXApp stopConnecting];
  152.     }
  153.     return self;
  154. }
  155.  
  156. - dataSourceOk:sender
  157. {
  158.     id dsConnector = getDSConnectorForSource(object);
  159.  
  160.     if ([sender tag]==0)  { // Want to connect a datasource
  161.         dsConnector = [[TDataSourceConnector alloc] init];
  162.         [dsConnector setSource:object];
  163.         [dsConnector setDestination:[NXApp connectDestination]];
  164.         [[NXApp activeDocument] addConnector:dsConnector];
  165.         [object setDataSource:[dsConnector destination]];
  166.         [[[dsConnector destination] class] methodSelectors:accessorStorage
  167.                                 includeAncestors:YES
  168.                                 filterWith:isAccessor];
  169.         [accessorBrowser loadColumnZero];
  170.         [sourceConnectButton setTitle:"Disconnect"];
  171.         [sourceConnectButton setTag:1];
  172.         [sourceDisplayButton setEnabled:YES];
  173.         [sourceDisplayButton setTitle:[[dsConnector destination] name]];
  174.     } else if ([sender tag]==1) { // Want to disconnect a datasource
  175.         [[NXApp activeDocument] removeConnector:dsConnector];
  176.         [dsConnector free];
  177.         [accessorStorage empty];
  178.         [accessorBrowser loadColumnZero];
  179.         [sourceConnectButton setTitle:"Connect"];
  180.         [sourceConnectButton setTag:0];
  181.         [sourceDisplayButton setEnabled:NO];
  182.         [sourceDisplayButton setTitle:""];
  183.     }
  184.     return self;
  185. }
  186.  
  187. - showConnection:conn
  188. {
  189.     const char *dsa, *ia;
  190.     char *str;
  191.     
  192.     // do the accessorBrowser
  193.     dsa = sel_getName([[conn binder] dataSourceAccessor]);
  194.     ia = sel_getName([[conn binder] interfaceAccessor]);
  195.     str = malloc((dsa?strlen(dsa):0)+(ia?strlen(ia):0)+10);
  196.     if (dsa && ia)
  197.         sprintf(str,"/%s/%s",dsa,ia);
  198.     else if (dsa)
  199.         sprintf(str,"/%s",dsa);
  200.     [accessorBrowser setPath:str];
  201.     free(str);
  202.  
  203.     return self;
  204. }
  205.  
  206. - selectConnection:sender
  207. {
  208.     id conn = [connectorList objectAt:[[browser matrixInColumn:0] selectedRow]];
  209.  
  210.     if (!conn) return self;
  211.  
  212.     selecting = YES;
  213.     // draw the connection
  214.     [NXApp displayConnectionBetween:[conn source] and:[conn destination]];
  215.     [accessorBrowser loadColumnZero];
  216.     [self showConnection:conn];
  217.  
  218.     [connectButton setTitle:"Disconnect"];
  219.     [connectButton setTag:1];
  220.     [connectButton setEnabled:YES];
  221.  
  222.     return self;
  223. }
  224.  
  225. - constructBinder
  226. {     //Assumes [NXApp isConnecting].
  227.     id binder;
  228.  
  229.     binder = [[TBinder alloc] init];
  230.  
  231.     // we set up the datasource after reading all connections
  232.     [binder setInterface:[NXApp connectDestination]];
  233.     [binder setDataSource:nil];
  234.  
  235.     if ([[accessorBrowser matrixInColumn:0] selectedCell]) {
  236.         [binder setDataSourceAccessor:
  237.             sel_getUid([[[accessorBrowser matrixInColumn:0] selectedCell]
  238.             stringValue])];
  239.         [binder setDataSourceModifier:
  240.             modifierFor([binder dataSourceAccessor])];
  241.     }
  242.     if ([[accessorBrowser matrixInColumn:1] selectedCell]) {
  243.         [binder setInterfaceAccessor:
  244.             sel_getUid([[[accessorBrowser matrixInColumn:1] selectedCell]
  245.             stringValue])];
  246.         [binder setInterfaceModifier:
  247.             modifierFor([binder interfaceAccessor])];
  248.     }
  249.     return binder;
  250. }
  251.  
  252. - ok:sender
  253. {
  254.     int i;
  255.     id aConnector, b;
  256.  
  257.     if ([sender tag]==0) { // Want to connect a binder
  258.         aConnector = [[TConnector alloc] init];
  259.         [aConnector setBinder:[self constructBinder] andSource:object];
  260.         [[NXApp activeDocument] addConnector:aConnector];
  261.         [connectorList addObject:aConnector];
  262.         [browser loadColumnZero];
  263.         b = [browser matrixInColumn:0];
  264.         [b selectCellAt:[b cellCount]-1 :0];
  265.         [connectButton setTitle:"Disconnect"];
  266.         [connectButton setTag:1];
  267.     } else if ([sender tag] ==1) {  // Want to disconnect a binder
  268.         i = [[browser matrixInColumn:0] selectedRow];
  269.         aConnector = [connectorList removeObjectAt:i];
  270.         
  271.         [[NXApp activeDocument] removeConnector:aConnector];
  272.         [aConnector free];
  273.         [browser loadColumnZero];
  274.         [[browser matrixInColumn:0] selectCellAt:-1 :-1];
  275.         [connectButton setTitle:"Connect"];
  276.         [connectButton setTag:0];
  277.     }
  278.     return [super ok:sender];
  279. }
  280.  
  281. - revert:sender
  282. {
  283.     int s,cond;
  284.     id dsConnector = getDSConnectorForSource(object);
  285.  
  286.     if (selecting) {
  287.         selecting = NO;
  288.         return self;
  289.     }
  290.  
  291.     if (![inspectorView isDescendantOf:[window contentView]]) {
  292.         id biv = [binderInspector inspectorView];
  293.         [[biv superview] replaceSubview:biv with:inspectorView];
  294.         [[inspectorView window] display];
  295.     }
  296.     if (dsConnector) {
  297.         [sourceDisplayButton setEnabled:YES];
  298.         [sourceDisplayButton setTitle:
  299.                         [[dsConnector destination] name]];
  300.         cond = ([NXApp isConnecting] &&
  301.                 [dsConnector destination]==[NXApp connectDestination]);
  302.         [sourceDisplayButton setState:cond];
  303.         [sourceConnectButton setTitle:"Disconnect"];
  304.         [sourceConnectButton setTag:1];
  305.         [[[dsConnector destination] class] methodSelectors:accessorStorage
  306.                                 includeAncestors:YES
  307.                                 filterWith:isAccessor];
  308.     } else {
  309.         [sourceDisplayButton setEnabled:NO];
  310.         [sourceDisplayButton setTitle:""];
  311.         [sourceConnectButton setTitle:"Connect"];
  312.         [sourceConnectButton setTag:0];
  313.     }
  314.     [sourceConnectButton setEnabled:[NXApp isConnecting]];
  315.  
  316.     [[NXApp activeDocument] listConnectors:connectorList forSource:object
  317.                             filterClass:[TConnector class]];
  318.     [browser loadColumnZero];
  319.     [accessorBrowser loadColumnZero];
  320.  
  321.     if ([NXApp isConnecting]) {
  322.         s = [connectorList indexOf:
  323.             getTConnectorForDestination([NXApp connectDestination])];
  324.         if (s == NX_NOT_IN_LIST) {
  325.             [[browser matrixInColumn:0] selectCellAt:-1 :-1];
  326.             [connectButton setTitle:"Connect"];
  327.             [connectButton setTag:0];
  328.             [connectButton setEnabled:YES];
  329.         } else {
  330.             [accessorBrowser loadColumnZero];
  331.             [self showConnection:[connectorList objectAt:s]];
  332.             [[browser matrixInColumn:0] selectCellAt:s :0];
  333.             [connectButton setTitle:"Disconnect"];
  334.             [connectButton setTag:1];
  335.             [connectButton setEnabled:YES];
  336.         }
  337.     } else {
  338.         [[browser matrixInColumn:0] selectCellAt:-1 :-1];
  339.         [connectButton setTitle:"No Selection"];
  340.         [connectButton setEnabled:NO];
  341.         [connectButton setTag:2];
  342.     }
  343.  
  344.     return [super revert:sender];
  345. }
  346.  
  347. - (BOOL)wantsButtons
  348. {
  349.     return NO;
  350. }
  351.  
  352. @end
  353.  
  354. @implementation TBinderList (ConnectionsInspector)
  355.  
  356. -(const char *)getConnectInspectorClassName
  357. {
  358.     NXEvent *ev = [NXApp currentEvent];
  359.  
  360.     // NOTE:  This doesn't work on PC's and most NextStations, due
  361.     // to the fact that control-alt is mapped to be a Help key!!!
  362.     // expect this to go away later with the more complete version of
  363.     // superclass-inspector access.
  364.     if (ev->flags & NX_ALTERNATEMASK)
  365.         return [super getConnectInspectorClassName];
  366.     else
  367.         return "TBinderListConnectInspector";
  368. }
  369.  
  370. -(const char *)getEditorClassName
  371. {
  372.     NXEvent *ev = [NXApp currentEvent];
  373.  
  374.     // lets try not to confuse people... unless they really want
  375.     // to be confused!!!
  376.     if (ev->flags & NX_ALTERNATEMASK)
  377.         return [super getConnectInspectorClassName];
  378.     else
  379.         return NULL;
  380. }
  381.  
  382. - (NXImage *)getIBImage
  383. {
  384.     return [NXImage findImageNamed:"TBinderListIcon"];
  385. }
  386.  
  387. @end
  388.  
  389.